// IngenicVideoSource.h
#ifndef INGENICVIDEOSOURCE_H
#define INGENICVIDEOSOURCE_H

#include "FramedSource.hh"
#include <vector>
#include <deque>
#include <chrono>
#include <map>
#include <thread>
#include <mutex>
#include <atomic>
#include <pthread.h>
#include <unistd.h>
#include <sys/time.h>
#include "IngenicEncoder.h"

// 君正SDK相关头文件
#include <imp/imp_common.h>
#include <imp/imp_encoder.h>
#include <imp/imp_framesource.h>
#include <imp/imp_isp.h>
#include <imp/imp_system.h>
#include <imp/imp_log.h>

// 君正SDK相关定义
#define FS_CHN_NUM 2
#define CH0_INDEX 0
#define CH1_INDEX 1
#define CHN0_EN 1
#define CHN1_EN 1

// 传感器配置
#define FIRST_SNESOR_NAME "gc5603"
#define FIRST_I2C_ADDR 0x31
#define FIRST_I2C_ADAPTER_ID 0
#define FIRST_SENSOR_WIDTH 1920
#define FIRST_SENSOR_HEIGHT 1080
#define FIRST_RST_GPIO GPIO_PA(18)
#define FIRST_PWDN_GPIO GPIO_PA(19)
#define FIRST_POWER_GPIO -1
#define FIRST_SENSOR_ID 0
#define FIRST_VIDEO_INTERFACE IMPISP_SENSOR_VI_MIPI_CSI0
#define FIRST_MCLK IMPISP_SENSOR_MCLK0
#define FIRST_DEFAULT_BOOT 0
#define FIRST_SENSOR_FRAME_RATE_NUM 25
#define FIRST_SENSOR_FRAME_RATE_DEN 1
#define FIRST_CROP_EN 0

// 编码器配置
#define BITRATE_720P_Kbs 2000
#define IMP_ENC_RC_MODE_CBR 1

// 第二通道分辨率
#define FIRST_SENSOR_WIDTH_SECOND 1280
#define FIRST_SENSOR_HEIGHT_SECOND 720

// Linux兼容性定义
#ifndef RGB
#define RGB(r,g,b) ((unsigned long)(((unsigned char)(r)|((unsigned short)((unsigned char)(g))<<8))|(((unsigned long)(unsigned char)(b))<<16)))
#endif

// 君正SDK相关结构体
struct chn_conf {
    unsigned int index; // 0 for main channel, 1 for second channel
    unsigned int enable;
    IMPEncoderProfile payloadType;
    IMPFSChnAttr fs_chn_attr;
    IMPCell framesource_chn;
    IMPCell imp_encoder;
};

// 全局变量声明
    extern struct chn_conf chn[FS_CHN_NUM];
    extern IMPSensorInfo sensor_info[1];

    // 君正SDK函数声明
    extern "C" {
        int sample_system_init();
        int sample_system_exit();
        int sample_framesource_init();
        int sample_framesource_exit();
        int sample_encoder_init();
        int sample_encoder_exit();
        int sample_framesource_streamon();
        int sample_framesource_streamoff();
        int sample_get_video_stream();
        int IngenicPutH264DataToBuffer(IMPEncoderStream *stream, int channelNum = 0);
    }

class IngenicVideoSource : public FramedSource {
public:
    static IngenicVideoSource* createNew(UsageEnvironment& env);
    void enableTimestampDisplay(bool enable) { m_showTimestamp = enable; }
    void enableLatencyDisplay(bool enable) { m_showLatency = enable; }
    void setResolution(int width, int height) { m_width = width; m_height = height; }
    void setFramerate(int fps) { m_fps = fps; }
    void setBitrate(int bitrate) { m_bitrate = bitrate; }

protected:
    IngenicVideoSource(UsageEnvironment& env);
    virtual ~IngenicVideoSource();

private:
    // 帧数据结构
    struct FrameData {
        std::vector<unsigned char> data;
        uint32_t frameId;
        std::chrono::steady_clock::time_point captureTime;
        unsigned int frameType; // 0=I帧, 1=P帧, 2=B帧, 3=SPS, 4=PPS
        int channel; // 通道号，默认为0
    };

    // 延时标记结构
    struct LatencyMarker {
        int x, y;
        int size;
        unsigned long color; // 使用unsigned long替代COLORREF
        std::chrono::steady_clock::time_point changeTime;
        uint32_t sequence;
    };

    virtual void doGetNextFrame();
    virtual unsigned maxFrameSize() const { return 200000; } // 增加缓冲区大小

    static void deliverFrame0(void* clientData);
    static void* captureThread(void* clientData);

    void startCapturing();
    void stopCapturing();
    void deliverFrame();
    void addFrameData(const unsigned char* data, unsigned size, unsigned frameType, int channelNum = 0);
    bool initializeIngenicSystem();
    bool captureAndEncodeOnce(std::vector<unsigned char>& outAnnexB);
    void annexBFromAvcc(const unsigned char* avcc, size_t avccSize,
        std::vector<unsigned char>& outSps, std::vector<unsigned char>& outPps);
    void drawTimestampAndLatency(int width, int height);
    void drawLatencyMarker();
    void updateLatencyMarker();
    int64_t calculateRealLatency();

    // 君正相关函数
    bool initIngenicEncoder();
    bool getIngenicFrame();
    bool encodeIngenicFrame();
    void cleanupIngenicSystem();

    // 成员变量
    std::atomic<bool> m_captureRunning;
    pthread_t m_captureThread;
    unsigned long m_frameCount;
    int m_width, m_height;
    int m_fps;
    int m_bitrate;
    unsigned m_eventTriggerId;
    bool m_isCurrentlyAwaitingData;
    bool m_encoderReady;
    pthread_mutex_t m_cs;
    static const unsigned m_maxQueueSize = 15; // 增加队列大小
    std::deque<FrameData> m_frameQueue;
    IngenicEncoder m_encoder;
    std::vector<unsigned char> m_sps, m_pps;

    // 时间显示和延时相关变量
    bool m_showTimestamp;
    bool m_showLatency;
    std::chrono::steady_clock::time_point m_startTime;
    std::chrono::steady_clock::time_point m_lastFrameTime;
    int64_t m_frameLatency;
    uint32_t m_frameIdCounter;
    std::map<uint32_t, std::chrono::steady_clock::time_point> m_frameTimestamps;

    // 延时标记相关变量
    LatencyMarker m_latencyMarker;
    std::chrono::steady_clock::time_point m_lastMarkerChange;
    uint32_t m_markerChangeCount;
    int64_t m_realEndToEndLatency;

    // 君正系统相关
    bool m_ingenicSystemInitialized;
    std::mutex m_ingenicMutex;
    
    // 统计信息
    uint64_t m_totalFrames;   // 处理的总帧数
    uint64_t m_droppedFrames; // 丢弃的帧数
};

#endif
